package com.wang.vagus.filter;

import com.alibaba.fastjson.JSON;
import com.wang.vagus.base.Result;
import com.wang.vagus.base.ResultEnum;
import com.wang.vagus.property.JwtExcludeUriProperties;
import com.wang.vagus.util.JwtTokenUtil;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Value("${jwt.enable}")
    private boolean jwtEnable;
    @Autowired
    private JwtExcludeUriProperties jwtExcludeUriProperties;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        List<String> uris = jwtExcludeUriProperties.getUris();
        if (jwtEnable){
            String requestURI = request.getRequestURI();
            if (!uris.contains(requestURI)){
                final String requestTokenHeader = request.getHeader("Authorization");
                String username = null;
                String jwtToken = null;
                // JWT Token is in the form "Bearer token". Remove Bearer word and get
                // only the Token
                if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
                    jwtToken = requestTokenHeader.substring(7);
                    try {
                        username = jwtTokenUtil.getUsernameFromToken(jwtToken);
                    } catch (IllegalArgumentException e) {
                        log.info("Unable to get JWT Token");
                    }  catch (MalformedJwtException e) {
                        log.info("JWT Token MalformedJwtException");
                        response.setContentType("application/json");
                        response.setCharacterEncoding("utf-8");
                        response.getWriter().write(JSON.toJSONString(Result.error(ResultEnum.TOKEN_FORMAT_EXCEPTION)));
                        return;
                    } catch (ExpiredJwtException e) {
                        log.info("JWT Token has expired");
                        response.setContentType("application/json");
                        response.setCharacterEncoding("utf-8");
                        response.getWriter().write(JSON.toJSONString(Result.error(ResultEnum.TOKEN_EXPIRED)));
                        return;
                    } catch (SignatureException e) {
                        log.info("JWT Token SignatureException");
                        response.setContentType("application/json");
                        response.setCharacterEncoding("utf-8");
                        response.getWriter().write(JSON.toJSONString(Result.error(ResultEnum.TOKEN_SIGNATURE_EXCEPTION)));
                        return;
                    }
                } else {
                    log.info("JWT Token does not begin with Bearer String");
                }
                // Once we get the token validate it.
                if (username != null) {
                    log.info("请求用户为:{}",username);
                }
            }
        }

        chain.doFilter(request, response);
    }
}
